// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2023, Phytium Technology Co., Ltd.
 * lixinde          <lixinde@phytium.com.cn>
 * Describes getting fdt node and fixup ddr node automatically.
 */

#include <common.h>
#include <malloc.h>
#include <init.h>
#include <linux/arm-smccc.h>
#include "../cpu.h"
#include "../parameter/parameter.h"
#include "ft_fdt_lib.h"

DECLARE_GLOBAL_DATA_PTR;

static uint32_t ft_fdt_fixup_dram(void)
{
	int nodeoffset, err;

	//get memory size
	mem_region_t dram_info;

	if (get_dram_info(&dram_info)) {
		printf("fdt :can not get dram info, skip memory node update\n");
		return 0;
	}

	printf("mb_count = 0x%llx\n", dram_info.mb_count);
	printf("mb_blocks[0].mb_size = 0x%llx\n", dram_info.mb_blocks[0].mb_size);
	printf("mb_blocks[1].mb_size = 0x%llx\n", dram_info.mb_blocks[1].mb_size);

	//dram_info.mb_count = 1;
	//dram_info.mb_blocks[1].mb_size = 0;
	//dram_info.mb_blocks[1].mb_start = 0x2000001000;

	if (dram_info.mb_count == 1) {
		//only one paragraph.Delete 01 node,fix 00 node
		printf("fdt : remove memory@1");
		fdt_remove_node("/memory@01");
		nodeoffset = fdt_get_offset("/memory@00");
		err = ft_fdt_set_mem_prop(nodeoffset, "reg",
			dram_info.mb_blocks[0].mb_start, dram_info.mb_blocks[0].mb_size);
		if (err) {
			printf("fdt : failed ft_fdt_fixup_dram\n");
			return err;
		}
	} else {
		//two paragraphs,both fixup
		nodeoffset = fdt_get_offset("/memory@00");
		err = ft_fdt_set_mem_prop(nodeoffset, "reg",
			dram_info.mb_blocks[0].mb_start, dram_info.mb_blocks[0].mb_size);
		if (err) {
			printf("fdt : failed ft_fdt_fixup_dram\n");
			return err;
		}

		nodeoffset = fdt_get_offset("/memory@01");
		err = ft_fdt_set_mem_prop(nodeoffset, "reg",
			dram_info.mb_blocks[1].mb_start, dram_info.mb_blocks[1].mb_size);
		if (err) {
			printf("fdt : failed ft_fdt fixup_dram\n");
			return err;
		}
	}
	printf("fdt : dram size 0x%llx update successfully\n", (0x80000000 + dram_info.mb_blocks[1].mb_size));

	return 0;
}

int ft_board_setup(void *blob, struct bd_info *bd)
{
	int err;

	printf("run in ft_board_setup\n");
	err = set_fdt_addr(blob);
	if (err)
		return err;

	err = ft_fdt_fixup_dram();
	if (err)
		return err;

	return 0;
}
